#ifndef	_BG_SCENE_H_
#define _BG_SCENE_H_

namespace script
{
	class	WriteLua;
}

namespace LuaPlus
{
	class LuaState;	
	class LuaObject;	
}

#include "editor/editor_main.h"
#include "math/spline2d.h"
#include <string>
#include <vector>
#include "ui/ui_sprite.h"

namespace	background
{
class	BGPath;
class	BGElement;
class	BGEditor;
class	BGWaypoint;

class	BGScene : public editor::GameBase
{
public:

								BGScene();
								~BGScene();
	void						FlushImages();

	BGScene*					GetSubScene(const math::Vec2& From, const math::Vec2& To);
	void						Tick(float dt);
	void						RenderBackground(float	Scale=1.0f);
	void						RenderForeground(float	Scale=1.0f);

	void						RenderDebug(const math::Vec2& Offset, float	Scale=1.0f);
	void						SaveFile(script::WriteLua& WL);
	void						LoadFile(LuaPlus::LuaState& State, bool LoadBGTiles = true);
	void						LoadFile(LuaPlus::LuaObject& State, bool LoadBGTiles = true);
	virtual bool				Save(const std::string& File);
	virtual bool				Load(const std::string& File);
	virtual bool				Clear(){ return true; };
	virtual void				ResetScene();

	void						SetBackground(const std::string& File);
	void						DeleteObjects();

	bool						HasTiles() { return m_TileA != NULL; };
	// elements
	bool						DeleteElement(const math::Vec2& Pos);
	bool						DropElement(BGElement* pElement);
	bool						DropElements(const std::string& SubStr);
	void						AddElement(BGElement* pElement);
	BGElement*					GetElement(const math::Vec2& Pos);
	BGElement*					GetElement(const std::string& Name);
	void						ResetElements();

	// paths
	bool						AddPath(const math::SplineCache2D& Cache, int Index = -1);
	BGPath*						GetPath(const math::Vec2& Pos);
	BGPath*						GetPath( int ID);
	bool						DeletePath(const math::Vec2& Pos);

	// waypoints
	BGWaypoint*				AddWaypoint(const math::Vec2& Pos, int Index);
	BGWaypoint*				GetWaypointFromID(int	Index);
	BGWaypoint*				GetWaypoint(const math::Vec2& Pos, bool Delete);

	// get the sets
	std::vector<BGPath*>*		GetPaths() { return &m_Paths; };
	std::vector<BGWaypoint*>*	GetWaypoints() { return &m_Waypoints; };


	// tiles
	void						ClearTiles();
	void						SetBackgroundTile(int Width, int Height, const math::Vec2& TileSize);
	void						SetTile(int x, int y, const std::string& File, int Rotation = 0);
	const math::Vec2&			GetTileSize() const { return m_TileSize; };	

	// accessors
	const math::Vec2&			GetMin() const { return m_Min; };
	const math::Vec2&			GetMax() const { return m_Max; };
	const math::Vec2&			GetOffset()
	{
		return m_Offset;
	}
	void						SetOffset(const math::Vec2& V);
	BGEditor*					GetEditor() { return m_pEditor; };
	void						SetGrid(const math::Vec2& GO, const math::Vec2& GS) { m_GridOffset = GO; m_GridSize = GS; }; 
	int							GetWidth() const { return m_Width; }
	int							GetHeight() const { return m_Height; }
	const std::string&			GetFile() const { return m_File; };
	bool						IsEditing() const { return m_pEditor ? true : false; }

	// input
	virtual	void				MouseButtonPressed(input::Mouse::BUTTON_STATE* pKey, const math::Vec2& Pos);
	virtual	void				MouseButtonReleased(input::Mouse::BUTTON_STATE* pKey, const math::Vec2& Pos);
	virtual void				MouseMove(const math::Vec2& From, const math::Vec2& To);
	virtual void				MouseWheelMove(int WheelInfo, const math::Vec2& Pos);
	virtual void				KeyPressed(input::Keyboard::KEY* pKey);
	virtual void				KeyDown(input::Keyboard::KEY* pKey);
	static	void				Register(LuaPlus::LuaState* _pScript);
	math::Vec2					ConvertFromFile(const math::Vec2& P);

	void						SetMax(const math::Vec2&	Max) { m_Max = Max; };
	void						MaxFromBG();
	bool						UpdateScroll(const math::Vec2& MousePos, float dt);
	float						GetScale() { return m_Scale; };
	void						SetActivationKey(int KeyID) { m_ActivationKey = KeyID; };
	static void					SetBaseScreen(const math::Vec2& P) { s_BaseScreen = P; };
	void						SetWrapping(bool b) { m_Wrapping = b; };
	bool						IsWrapping() const { return m_Wrapping; };

	// add a component. Basically allows a game to add custom BGElement's, for example for custom SFX
	typedef BGElement*			(*CreateChunkCB)(BGScene* pMain);
	static	void				RegisterComponent(const std::string& Name, CreateChunkCB pCreateCB, int KeyID, editor::EditorMain::CreateBrushCB pBrushCB);
	BGElement*					GetCustomElement(const std::string& Name);

private:
	math::Vec2					m_TileSize;
	int							m_Width, m_Height;
	struct						BgTile
	{
		ui::UISprite			Background;
		std::string				BackgroundImg;
		int						x, y, Rot;
	};
	BgTile*						m_TileA;

	// single screen images tend to just use the old method
	ui::UISprite				m_Background;
	std::string					m_BackgroundImg;

	static const int			MAX_WP_COUNT = 255;
	math::Vec2					m_Min, m_Max;
	std::vector<BGElement*>		m_BackElements;
	std::vector<BGElement*>		m_FrontElements;
	std::vector<BGPath*>		m_Paths;
	std::vector<BGWaypoint*>	m_Waypoints;
	BGEditor*					m_pEditor;
	int							m_PathIndex;

	math::Vec2					m_GridOffset, m_GridSize;
	math::Vec2					m_Offset;
	float						m_Scale;	
	float						m_AspectScale;

	int							m_ActivationKey;
	bool						m_Wrapping;

	std::string					m_File;
	static math::Vec2			s_BaseScreen;	
	bool						m_IsFirstTick;


};
};

#endif // _BG_SCENE_H_